package com.hunan.api.catv.service.biz.activity;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.JsonObject;
import com.hunan.api.catv.common.CacheName;
import com.hunan.api.catv.common.Constants;
import com.hunan.api.catv.common.ConstantsMsg;
import com.hunan.api.catv.entity.ServiceResult;
import com.hunan.api.catv.entity.enums.FilesStateEnum;
import com.hunan.api.catv.entity.enums.FilesTypeEnum;
import com.hunan.api.catv.entity.po.ActivityNews;
import com.hunan.api.catv.entity.po.ActivityVideo;
import com.hunan.api.catv.entity.po.Files;
import com.hunan.api.catv.entity.po.News;
import com.hunan.api.catv.entity.vo.*;
import com.hunan.api.catv.mq.MqConstants;
import com.hunan.api.catv.service.ResultService;
import com.hunan.api.catv.service.biz.cache.CacheBiz;
import com.hunan.api.catv.service.biz.files.FilesBiz;
import com.hunan.api.catv.service.biz.member.MemberBiz;
import com.hunan.api.catv.service.biz.mq.MqBiz;
import com.hunan.api.catv.service.biz.news.NewsBiz;
import com.hunan.api.catv.service.impl.activity.ActivityVideoService;
import com.hunan.api.catv.service.impl.news.NewsService;
import com.hunan.api.catv.service.impl.tencent_cloud.tms.TmsService;
import com.hunan.api.catv.utils.GsonUtils;
import com.hunan.api.catv.utils.PageUtils;
import com.hunan.api.catv.utils.RedisUtils;
import com.tencentcloudapi.tms.v20200713.models.TextModerationResponse;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.text.MessageFormat;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


@Service
@CacheConfig(cacheNames = CacheName.activityVideo)
public class ActivityVideoBiz extends ResultService {

    @Autowired
    ActivityVideoService activityVideoService;

    @Autowired
    ActivityBiz activityBiz;

    @Autowired
    CacheBiz cacheBiz;

    @Autowired
    MqBiz mqBiz;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    MemberBiz memberBiz;

    @Autowired
    FilesBiz filesBiz;

    @Autowired
    ActivityVideoBiz activityVideoBiz;

    @Autowired
    private TmsService tmsService;

    @Autowired
    private NewsBiz newsBiz;

    @Autowired
    private NewsService newsService;


    public ServiceResult add(Integer activityId, Integer memberId, String fileId, String cover) {
        ActivityVideo activityVideo = new ActivityVideo();
        activityVideo.setMemberId(memberId);
        activityVideo.setActivityId(activityId);
        activityVideo.setFileId(fileId);
        activityVideo.setCover(cover);
        activityVideo.setState(FilesStateEnum.process.getCode());
        ServiceResult addResult = activityVideoService.add(activityVideo);
        if (addResult.getStatus()) {
            Files files = new Files();
            files.setFileId(fileId);
            FilesVo filesVo = filesBiz.getByFileId(fileId);
            if (ObjectUtils.isEmpty(filesVo)) {
                files.setCover(cover);
                files.setName(MessageFormat.format(Constants.activity_video, activityId, memberId));
                files.setType(FilesTypeEnum.video.getCode());
                files.setIsActivity(1);
                return filesBiz.add(files);
            } else {
                files.setCover(cover);
                files.setName(MessageFormat.format(Constants.activity_video, activityId, memberId));
                files.setIsActivity(1);
                files.setfId(filesVo.getfId());
                return filesBiz.update(files);
            }

        }
        return addResult;
    }

    public ServiceResult edit(ActivityVideo activityVideo) {
        return activityVideoService.update(activityVideo);
    }

    public ServiceResult editState(String fileId, Integer state) {
        ActivityVideoVo activityVideoVo = activityVideoBiz.getByFileId(fileId);
        if (!ObjectUtils.isEmpty(activityVideoVo)) {
            ActivityVideo activityVideo = new ActivityVideo();
            activityVideo.setId(activityVideoVo.getId());
            activityVideo.setState(state);
            return activityVideoService.update(activityVideo);
        }
        return buildFail(ConstantsMsg.admin_edit_fail);
    }

    public ActivityVideoVo getByFileId(String fileId) {
        ActivityVideo activityVideo = new ActivityVideo();
        activityVideo.setFileId(fileId);
        return activityVideoService.get(activityVideo);
    }

    //    @Cacheable(unless = "#result == null",cacheManager = "cacheManager1m")
    public PageInfo<ActivityVideoVo> page(int pageNum, int pageSize, Integer activityId) {
        PageHelper.startPage(pageNum, pageSize);
        ActivityVideo activityVideo = new ActivityVideo();
        activityVideo.setState(1);
        activityVideo.setActivityId(activityId);
        List<ActivityVideoVo> list = activityVideoService.list(activityVideo);
        if (!ObjectUtils.isEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                ActivityVideoVo av = list.get(i);
                av.setMember(memberBiz.simpleInfo(av.getMemberId()));
                String fileId = av.getFileId();
                FilesVo filesVo = filesBiz.getByFileId(fileId);
                if (ObjectUtils.isEmpty(filesVo)) {
                    list.remove(i);
                } else {
                    filesVo.setDetail(null);
                    av.setVideo(filesVo);
                }
            }
        }
        PageInfo<ActivityVideoVo> activityVideoVoPageInfo = new PageInfo<>(list);
        List<Integer> newsIds = new ActivityNews().selectList(new QueryWrapper<ActivityNews>().eq(ActivityNews.ACTIVITY_ID, activityId)).stream().map(ActivityNews::getNewsId).collect(Collectors.toList());
        if (!newsIds.isEmpty()) {
            newsIds = new News().selectList(new QueryWrapper<News>()
                    .eq(News.VIDEO_SOURCE, 1)
                    .eq(News.DELETED, 1)
                    .eq(News.STATE, 1)
                    .in(News.NEWSID, newsIds)
                    .orderByDesc(News.CTIME)
            ).stream().map(News::getNewsId).collect(Collectors.toList());
        }
        if (newsIds.isEmpty()) {
            return activityVideoVoPageInfo;
        }

        newsIds.forEach(newsId -> {
            String newsKey = MessageFormat.format(CacheName.getNewsInfo, String.valueOf(newsId));
            NewsVo newsVo = (NewsVo) redisUtils.get(newsKey);
            if (newsVo == null) {
                newsVo = newsService.getById(newsId);
            }
            if (newsVo != null) {
                ActivityVideoVo activityVideoVo = new ActivityVideoVo();
                activityVideoVo.setId(newsVo.getNewsId());
                activityVideoVo.setMember(memberBiz.simpleInfo(newsVo.getMemberId()));
                String fileId = newsVo.getFileId();
                FilesVo filesVo = filesBiz.getByFileId(fileId);
                if (ObjectUtils.isEmpty(filesVo)) {
                    filesVo = new FilesVo();
                    filesVo.setUrl(newsVo.getUrl());
                    filesVo.setName(newsVo.getTitle());
                    filesVo.setFileId(fileId);
                    filesVo.setCover(newsVo.getPicMinivideo());
                }
                filesVo.setDetail(null);
                activityVideoVo.setVideo(filesVo);
                activityVideoVo.setActivityId(activityId);
                activityVideoVo.setCover(newsVo.getPicMinivideo());
                if (newsVo.getcTime() != null) {
                    activityVideoVo.setcTime(Timestamp.valueOf(new Date(newsVo.getcTime() * 1000L).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime()));
                }
                activityVideoVo.setFileId(newsVo.getFileId());
                activityVideoVo.setMemberId(newsVo.getMemberId());
                activityVideoVo.setState(newsVo.getState());
                list.add(activityVideoVo);

            }
        });
        return PageUtils.list2PageInfo(pageNum, pageSize, list, (int) (activityVideoVoPageInfo.getTotal() + newsIds.size()));
    }

    public ServiceResult upload(Integer activityId, Integer memberId, String fileId, String cover) {
        JsonObject msg = new JsonObject();
        msg.addProperty("activityId", activityId);
        msg.addProperty("memberId", memberId);
        msg.addProperty("fileId", fileId);
        mqBiz.push(MqConstants.activity_upload_exchange, MqConstants.activity_upload_routingkey, GsonUtils.toJson(msg));
        return buildOK(true, ConstantsMsg.activity_upload_success);
    }

    public PageInfo<ActivityVideoVo> page(int pageNum, int pageSize, Integer activityId, Integer state) {
        PageHelper.startPage(pageNum, pageSize);
        ActivityVideo activityVideo = new ActivityVideo();
        activityVideo.setState(state);
        activityVideo.setActivityId(activityId);
        List<ActivityVideoVo> list = activityVideoService.list(activityVideo);
        list.forEach(av -> {
            Integer memberId = av.getMemberId();
            av.setMember(memberBiz.simpleInfo(memberId));
            String fileId = av.getFileId();
            FilesVo filesVo = filesBiz.getByFileId(fileId);
            if (!ObjectUtils.isEmpty(filesVo)) {
                filesVo.setDetail(null);
            }
            av.setVideo(filesVo);
            av.setActivityVo(activityBiz.getById(av.getActivityId()));
        });
        return new PageInfo<ActivityVideoVo>(list);
    }

    public ServiceResult audit(Integer id, Integer state) {
        ActivityVideo activityVideo = new ActivityVideo();
        activityVideo.setState(state);
        activityVideo.setId(id);
        ServiceResult auditResult = activityVideoService.update(activityVideo);
        if (auditResult.getStatus()) {
            //如果用户视频被拒绝,将用户状态改为未参加
            if (FilesStateEnum.invalid.getCode().equals(state) ) {
                ActivityVideoVo activityVideoVo = activityVideoService.getById(id);
                if (!ObjectUtils.isEmpty(activityVideoVo) && !ObjectUtils.isEmpty(activityVideoVo.getMemberId())) {
                    Integer memberId = activityVideoVo.getMemberId();
                    activityBiz.cancel(memberId, activityVideoVo.getActivityId());
                    String simpleInfoKey = MessageFormat.format(CacheName.activityInfo, String.valueOf(activityVideoVo.getActivityId()));
                    cacheBiz.flushCacheInfo("activityInfoCache?" + activityVideoVo.getActivityId(), simpleInfoKey);
                }
            }
            redisUtils.delObjectCacheList(CacheName.activityVideo);
            mqBiz.push(MqConstants.add_ticket_exchange, MqConstants.add_ticket_key, id);
        }
        return auditResult;
    }

    public ServiceResult delete(Integer id, String fileId) {
        ActivityVideoVo activityVideoVo = activityVideoService.getById(id);
        ServiceResult deleteResult = activityVideoService.delete(id);
        if (deleteResult.getStatus()) {
            ServiceResult fileResult = filesBiz.deleteByFileId(fileId);
            if (fileResult.getStatus()) {
                //如果用户视频被删除,将用户状态改为未参加
                if (!ObjectUtils.isEmpty(activityVideoVo) && !ObjectUtils.isEmpty(activityVideoVo.getMemberId())) {
                    Integer memberId = activityVideoVo.getMemberId();
                    activityBiz.cancel(memberId, activityVideoVo.getActivityId());
                    String simpleInfoKey = MessageFormat.format(CacheName.activityInfo, String.valueOf(activityVideoVo.getActivityId()));
                    cacheBiz.flushCacheInfo("activityInfoCache?" + activityVideoVo.getActivityId(), simpleInfoKey);
                }
                redisUtils.delObjectCacheList(CacheName.activityVideo);
                return buildOK(true);
            }
        }
        return buildFail(ConstantsMsg.admin_del_fail);
    }

    public ActivityVideoVo getById(Integer id) {
        ActivityVideo activityVideo = new ActivityVideo();
        activityVideo.setId(id);
        return activityVideoService.get(activityVideo);
    }

    public List<ActivityVideoVo> list(Integer activityId) {
        ActivityVideo activityVideo = new ActivityVideo();
        activityVideo.setActivityId(activityId);
        activityVideo.setState(1);
        return activityVideoService.list(activityVideo);
    }

    @Transactional
    public ServiceResult uploadNews(Integer activityId, Integer memberId, NewsVo newsVo) {
        List<Integer> newsIds = new ActivityNews().selectList(new QueryWrapper<ActivityNews>().eq(ActivityNews.ACTIVITY_ID, activityId)).stream().map(ActivityNews::getNewsId).collect(Collectors.toList());
        if (!newsIds.isEmpty()) {
            newsIds = new News().selectList(new QueryWrapper<News>()
                    .eq(News.MEMBER_ID, memberId)
                    .eq(News.VIDEO_SOURCE, 1)
                    .eq(News.DELETED, 1)
                    .in(News.NEWSID, newsIds)
                    .orderByDesc(News.CTIME)
            ).stream().map(News::getNewsId).collect(Collectors.toList());
        }
        if (!newsIds.isEmpty()) {
            String newsKey = MessageFormat.format(CacheName.getNewsInfo, String.valueOf(newsIds.get(0)));
            NewsVo exsitNewsVo = (NewsVo) redisUtils.get(newsKey);
            if (exsitNewsVo == null) {
                exsitNewsVo = newsService.getById(newsIds.get(0));
            }
            if (exsitNewsVo == null || exsitNewsVo.getState().equals(5)) {
            } else {
                return buildFail(ConstantsMsg.admin_add_fail_repeat);
            }
        }


        TextModerationResponse response = tmsService.textModeration(newsVo.getTitle().replaceAll("\\s", ""));
        String suggestion = response.getSuggestion();
        if ("Pass".equals(suggestion) || "Review".equals(suggestion)) {
            if ("Review".equals(suggestion)) {
                //标题疑似视频状态设为禁用
                newsVo.setState(0);
            } else {
                //上传视频默认状态为7腾讯云审核
                newsVo.setState(7);
            }

            News news = new News();
            BeanUtils.copyProperties(newsVo, news);
            //用户发布视频来源活动视频
            news.setVideoSource(1);
            news.setCTime(DateTime.now().getMillis() / 1000L);
            news.setMemberId(memberId);
            news.setVideoProportion(StringUtils.isEmpty(newsVo.getVideoProportion()) ? "16:9" : newsVo.getVideoProportion());

            boolean insert = news.insert();
            if (insert) {
                //发布视频存入缓存
                ActivityNews activityNews = new ActivityNews();
                activityNews.setActivityId(activityId);
                activityNews.setNewsId(news.getNewsId());
                activityNews.insert();
                NewsVo newsInfo = newsBiz.getNewsInfo(news.getNewsId());
                //視頻審核
//				mqBiz.push(MqConstants.RELEASE_VEDIO_EXCHANGE,MqConstants.RELEASE_VEDIO_ROUTINGKEY, GsonUtils.toJson(newsInfo));
                return buildOK(true, ConstantsMsg.admin_add_success);
            }
            return buildFail(ConstantsMsg.admin_add_fail);
        } else {
            return buildFail(ConstantsMsg.admin_add_fail_title);
        }
    }


    public Object myNews(Integer activityId, Integer memberId) {
        List<Integer> newsIds = new ActivityNews().selectList(new QueryWrapper<ActivityNews>().eq(ActivityNews.ACTIVITY_ID, activityId)).stream().map(ActivityNews::getNewsId).collect(Collectors.toList());
        if (!newsIds.isEmpty()) {
            newsIds = new News().selectList(new QueryWrapper<News>()
                    .eq(News.MEMBER_ID, memberId)
                    .eq(News.VIDEO_SOURCE, 1)
                    .eq(News.DELETED, 1)
                    .in(News.NEWSID, newsIds)
                    .orderByDesc(News.CTIME)
            ).stream().map(News::getNewsId).collect(Collectors.toList());
        }
        if (newsIds.isEmpty()) {
            return null;
        }
        String newsKey = MessageFormat.format(CacheName.getNewsInfo, String.valueOf(newsIds.get(0)));
        NewsVo newsVo = (NewsVo) redisUtils.get(newsKey);
        return newsVo;
    }

    //	@Cacheable(unless = "#result == null")
    public PageInfo<JSONObject> news(Integer activityId, Integer pageNum, Integer pageSize) {

        PageHelper.startPage(pageNum, pageSize);
        ActivityVideo activityVideo = new ActivityVideo();
        activityVideo.setState(1);
        activityVideo.setActivityId(activityId);
        List<ActivityVideoVo> list = activityVideoService.list(activityVideo);
        List<JSONObject> newsVoList = new ArrayList<>();
        if (!ObjectUtils.isEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                ActivityVideoVo av = list.get(i);
                SimpleMemberVo simpleMemberVo = memberBiz.simpleInfo(av.getMemberId());
                String fileId = av.getFileId();
                FilesVo filesVo = filesBiz.getByFileId(fileId);
                NewsVo newsVo = new NewsVo();
                newsVo.setFileId(av.getFileId());
                newsVo.setState(av.getState());
                newsVo.setPicMinivideo(av.getCover());
                if (StringUtils.isEmpty(av.getCover())) {
                    newsVo.setPicMinivideo(filesVo.getCover());
                }
                newsVo.setNewsId(av.getId());
                newsVo.setUrl(filesVo.getUrl());
                newsVo.setTitle(filesVo.getName());
                newsVo.setMemberId(av.getMemberId());
                newsVo.setNickName(simpleMemberVo.getNickName());
                newsVo.setAvatarUrl(simpleMemberVo.getAvatarUrl());
                if (ObjectUtils.isEmpty(filesVo)) {
                    list.remove(i);
                } else {
//                    filesVo.setDetail(null);
//                    av.setVideo(filesVo);
                    JSONObject jsonObject = JSONUtil.parseObj(newsVo, false);
                    jsonObject.set("activityId", activityId);
                    newsVoList.add(jsonObject);
                }
            }
        }

        List<Integer> newsIds = new ActivityNews().selectList(new QueryWrapper<ActivityNews>().eq(ActivityNews.ACTIVITY_ID, activityId)).stream().map(ActivityNews::getNewsId).collect(Collectors.toList());
        if (!newsIds.isEmpty()) {
            newsIds = new News().selectList(new QueryWrapper<News>()
                    .eq(News.VIDEO_SOURCE, 1)
                    .eq(News.DELETED, 1)
                    .eq(News.STATE, 1)
                    .in(News.NEWSID, newsIds)
                    .orderByDesc(News.CTIME)
            ).stream().map(News::getNewsId).collect(Collectors.toList());
        }
        if (newsIds.isEmpty()) {
            return PageUtils.list2PageInfo(pageNum, pageSize, newsVoList);
        }

        newsIds.forEach(newsId -> {
            String newsKey = MessageFormat.format(CacheName.getNewsInfo, String.valueOf(newsId));
            NewsVo newsVo = (NewsVo) redisUtils.get(newsKey);
            if (newsVo == null) {
                newsVo = newsService.getById(newsId);
                MemberVo info = memberBiz.info(newsVo.getMemberId());
                if (info != null) {
                    newsVo.setNickName(info.getNickName());
                    newsVo.setAvatarUrl(info.getAvatarUrl());
                }
            }
            if (newsVo != null) {
                JSONObject jsonObject = JSONUtil.parseObj(newsVo, false);
                jsonObject.set("activityId", activityId);
                newsVoList.add(jsonObject);
            }
        });
        int size = newsVoList.size();
        Integer count = (Integer) Optional.ofNullable(redisUtils.hget("activity_participate_news_count", String.valueOf(activityId))).orElse(0);
        if (count.intValue() != size) {
            int memberNum = newsVoList.parallelStream().map(jsonObject -> jsonObject.get("nickName")).collect(Collectors.toSet()).size();
            redisUtils.hset("activity_participate_news_count", String.valueOf(activityId), size);
            redisUtils.hset("activity_participate_member_count", String.valueOf(activityId), memberNum);
            String simpleInfoKey = MessageFormat.format(CacheName.activityInfo, String.valueOf(activityId));
            cacheBiz.flushCacheInfo("activityInfoCache?" + activityId, simpleInfoKey);
        }
        return PageUtils.list2PageInfo(pageNum, pageSize, newsVoList);
    }

    public List<NewsVo> newsList(Integer activityId) {
        List<NewsVo> result = new ArrayList<>();
        List<Integer> newsIds = new ActivityNews().selectList(new QueryWrapper<ActivityNews>().eq(ActivityNews.ACTIVITY_ID, activityId)).stream().map(ActivityNews::getNewsId).collect(Collectors.toList());
        if (!newsIds.isEmpty()) {
            newsIds = new News().selectList(new QueryWrapper<News>()
                    .eq(News.VIDEO_SOURCE, 1)
                    .eq(News.DELETED, 1)
                    .eq(News.STATE, 1)
                    .in(News.NEWSID, newsIds)
                    .orderByDesc(News.CTIME)
            ).stream().map(News::getNewsId).collect(Collectors.toList());
        }
        if (newsIds.isEmpty()) {
            return null;
        }
        newsIds.forEach(newsId -> {
            String newsKey = MessageFormat.format(CacheName.getNewsInfo, String.valueOf(newsId));
            NewsVo newsVo = (NewsVo) redisUtils.get(newsKey);
            if (newsVo == null) {
                newsVo = newsService.getById(newsId);
                MemberVo info = memberBiz.info(newsVo.getMemberId());
                if (info != null) {
                    newsVo.setNickName(info.getNickName());
                    newsVo.setAvatarUrl(info.getAvatarUrl());
                }
            }
            if (newsVo != null) {
                result.add(newsVo);
            }
        });
        return result;
    }
}
